package dcq;

import org.gdal.gdal.gdal;
import org.gdal.ogr.*;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * @Classname GDALHelper
 * @Description GDAL读取GDB
 * @Date 2024/5/14 16:27
 * @Created by trs
 */
public class GDALHelper {

    public static final PropertyGetter stringPropertyGetter = (feature, index) -> feature.GetFieldAsString(index);
    /**
     * feature.GetFieldType(index)得到一个属性类型的int值,该值对应具体类型
     */
    public static final PropertyGetter[] propertyGetters = new PropertyGetter[]{
            (feature, index) -> feature.GetFieldAsInteger(index),//0	Integer
            (feature, index) -> feature.GetFieldAsIntegerList(index),//1	IntegerList
            (feature, index) -> feature.GetFieldAsDouble(index),//2	Real
            (feature, index) -> feature.GetFieldAsDoubleList(index),//3	RealList
            stringPropertyGetter,//4	String
            (feature, index) -> feature.GetFieldAsStringList(index),//5	StringList
            stringPropertyGetter,//6	(unknown)
            stringPropertyGetter,//7	(unknown)
            (feature, index) -> feature.GetFieldAsBinary(index),//8	Binary
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                Date date = Date.valueOf(LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]));
                return date;
            },//9	Date
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                float fSecond = pfSecond[0];
                int s = (int) fSecond;
                int ns = (int) (1000000000 * fSecond - s);
                Time time = Time.valueOf(LocalTime.of(pnHour[0], pnMinute[0], s, ns));
                return time;
            },// 10	Time
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                float fSecond = pfSecond[0];
                int s = (int) fSecond;
                int ns = (int) (1000000000 * fSecond - s);
                LocalDateTime localDateTime = LocalDateTime.of(
                        LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]),
                        LocalTime.of(pnHour[0], pnMinute[0], s, ns)
                );
                Timestamp timestamp = Timestamp.valueOf(localDateTime);
                return timestamp;
            },//11	DateTime
            (feature, index) -> feature.GetFieldAsInteger64(index),//12	Integer64
            (feature, index) -> feature.GetFieldAsIntegerList(index),//13 Integer64List
            //>=14	(unknown)
    };

    static {

        /*   准备工作   */
        gdal.AllRegister();
        //注册所有驱动
        ogr.RegisterAll();
        //支持中文路径
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        //属性表支持中文
        gdal.SetConfigOption("SHAPE_ENCODING", "CP936");


    }

    public static void main(String[] args) {

    }

    public static Object getProperty(Feature feature, int index) {
        int type = feature.GetFieldType(index);
        PropertyGetter propertyGetter;
        if (type < 0 || type >= propertyGetters.length) {
            propertyGetter = stringPropertyGetter;
        } else {
            propertyGetter = propertyGetters[type];
        }
        try {
            return propertyGetter.get(feature, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 属性获取器
     */
    @FunctionalInterface
    public interface PropertyGetter {
        Object get(Feature feature, int index);
    }
}
